import { Engine } from "../engine";
import { SelfDefFundDouble } from "./selfDefFundDouble";
import { CsDouble } from "../common/csDouble";

// 采购销售单中不同贵金属收付账单金额

export class OrderSelfDefFundData {
    constructor() {
        this._selfDefFundDoubles = [];
    }


    get selfDefFundAccount(){
        return this._selfDefFundDoubles;
    }


    /**
     * 添加 CommodityBatchWithTax
     * 如果没有对应的 账号，添加账号和金额，如果有对应账号增加金额
     * 如果没有找到账号，抛出异常
     * @returns 
     */
    addCommodityBatch(batch) {
        if (batch && batch.isMetalTradeBatch) {
            let metalAccountTypeId = batch.commodity.metalAccountTypeId;
            let fundDouble = this._selfDefFundDoubles.find(element => element.selfDefFundAccountType.id === metalAccountTypeId);
            if (fundDouble == null) {
                // 商户支持的账户类型
                let customerFundAccountTypeList = Engine.profile.org.customerFundAccountTypeList;

                let fundType = customerFundAccountTypeList.find(element => element.id === metalAccountTypeId);

                if (fundType) {
                    // isSettleMetal = true 表示来金，则来金和应收应付金都是 batch.countAfterDiscount
                    let fundCount = new SelfDefFundDouble(fundType, batch.actualMetalCount, batch.expectMetalCount);
                    this.addSelfDefFundAccount(fundCount);
                }
                else {
                    throw new Error("Invalid fund account type id: " + metalAccountTypeId);
                }
            }
            else {

                fundDouble.addCount(batch.actualMetalCount);
                fundDouble.addExpectCount(batch.expectMetalCount);

            }
        }
        else {
            console.log("batch is null or batch.isMetalTradeBatch not match");
            return -1;
        }

        console.log("metalFundAccountPrice addCommodityBatch: ", this);
    }

    /**
 * 移除 CommodityBatchWithTax
 * 如果没有对应的 账号，添加账号和金额，如果有对应账号增加金额
 * 如果没有找到账号，抛出异常
 * @returns 
 */
    removeCommodityBatch(batch) {
        if (batch && batch.isMetalTradeBatch) {
            let metalAccountTypeId = batch.commodity.metalAccountTypeId;
            let fundDouble = this._selfDefFundDoubles.find(element => element.selfDefFundAccountType.id === metalAccountTypeId);
            if (fundDouble) {

                // 扣除应收，应付金
                fundDouble.subCount(batch.actualMetalCount);


                fundDouble.subExpectCount(batch.expectMetalCount);

            }
        }
        else {
            console.log("batch is null");
            return -1;
        }
    }

    /**
    * 添加 MentalRefiningBatch
    * 如果没有对应的 账号，添加账号和金额，如果有对应账号增加金额
    * 如果没有找到账号，抛出异常
    * @returns 
    */
    addMentalRefiningBatch(batch) {
        if (batch && batch.isMetalTradeBatch) {
            let metalAccountTypeId = batch.commodity.metalAccountTypeId;
            let fundDouble = this._selfDefFundDoubles.find(element => element.selfDefFundAccountType.id === metalAccountTypeId);
            if (fundDouble == null) {
                // 商户支持的账户类型
                let customerFundAccountTypeList = Engine.profile.org.customerFundAccountTypeList;

                let fundType = customerFundAccountTypeList.find(element => element.id === metalAccountTypeId);

                if (fundType) {
                    // isSettleMetal = true 表示来金，则来金和应收应付金都是 batch.countAfterDiscount
                    let fundCount = new SelfDefFundDouble(fundType, CsDouble.zero(), batch.realReturn);
                    this.addSelfDefFundAccount(fundCount);
                }
                else {
                    throw new Error("Invalid fund account type id: " + metalAccountTypeId);
                }
            }
            else {

                //fundDouble.addCount(CsDouble.zero());
                fundDouble.addExpectCount(batch.realReturn);

            }
        }
        else {
            console.log("batch is null or batch.isMetalTradeBatch not match");
            return -1;
        }

        console.log("metalFundAccountPrice addCommodityBatch: ", this);
    }

    /**
     * 移除 CommodityBatchWithTax
     * 如果没有对应的 账号，添加账号和金额，如果有对应账号增加金额
     * 如果没有找到账号，抛出异常
     * @returns 
     */
    removeMentalRefiningBatch(batch) {
        if (batch && batch.isMetalTradeBatch) {
            let metalAccountTypeId = batch.commodity.metalAccountTypeId;
            let fundDouble = this._selfDefFundDoubles.find(element => element.selfDefFundAccountType.id === metalAccountTypeId);
            if (fundDouble) {

                // 扣除应收，应付金
                // fundDouble.subCount(CsDouble.zero());


                fundDouble.subExpectCount(batch.batch);

            }
        }
        else {
            console.log("batch is null");
            return -1;
        }
    }

    /**
     * Get the count of SelfDefFundDouble objects
     * @returns {number}
     */
    get count() {
        return this._selfDefFundDoubles.length;
    }
    /**
     * Get the list of SelfDefFundDouble objects
     * @returns {Array<SelfDefFundDouble>}
     */
    get selfDefFundDoubles() {
        return this._selfDefFundDoubles;
    }

    /**
     * Add a SelfDefFundDouble to the list
     * Ensures uniqueness by selfDefFundAccountType.id
     * @param {SelfDefFundDouble} selfDefFundDouble - The object to add
     * @returns {boolean} - True if added, false if duplicate ID exists
     */
    addSelfDefFundAccount(selfDefFundDouble) {
        if (!selfDefFundDouble || !selfDefFundDouble.selfDefFundAccountType) {
            return false;
        }

        const typeId = selfDefFundDouble.selfDefFundAccountType.id;

        // Check if an item with the same type ID already exists
        const existingIndex = this._selfDefFundDoubles.findIndex(item =>
            item.selfDefFundAccountType && item.selfDefFundAccountType.id === typeId
        );

        if (existingIndex >= 0) {
            // Replace existing item with the new one            
            return false;
        } else {
            // Add new item
            this._selfDefFundDoubles.push(selfDefFundDouble);
            return true;
        }
    }

    /**
     * Remove a SelfDefFundDouble by SelfDefFundAccountType ID
     * @param {string} typeId - The ID of the SelfDefFundAccountType to remove
     * @returns {boolean} - True if removed, false if not found
     */
    removeSelfDefFundAccountById(typeId) {
        const initialLength = this._selfDefFundDoubles.length;
        this._selfDefFundDoubles = this._selfDefFundDoubles.filter(item =>
            !item.selfDefFundAccountType || item.selfDefFundAccountType.id !== typeId
        );
        return this._selfDefFundDoubles.length < initialLength;
    }

    /**
     * Remove a SelfDefFundDouble by object reference
     * @param {SelfDefFundDouble} selfDefFundDouble - The object to remove
     * @returns {boolean} - True if removed, false if not found
     */
    removeSelfDefFundAccount(selfDefFundDouble) {
        const initialLength = this._selfDefFundDoubles.length;
        const typeId = selfDefFundDouble.selfDefFundAccountType?.id;

        if (!typeId) {
            return false;
        }

        this._selfDefFundDoubles = this._selfDefFundDoubles.filter(item =>
            !item.selfDefFundAccountType || item.selfDefFundAccountType.id !== typeId
        );
        return this._selfDefFundDoubles.length < initialLength;
    }

    /**
     * Get a SelfDefFundDouble by SelfDefFundAccountType ID
     * @param {string} typeId - The ID of the SelfDefFundAccountType to find
     * @returns {SelfDefFundDouble|null} - The found object or null
     */
    getSelfDefFundAccountById(typeId) {
        return this._selfDefFundDoubles.find(item =>
            item.selfDefFundAccountType && item.selfDefFundAccountType.id === typeId
        ) || null;
    }

    /**
     * Check if a SelfDefFundDouble with the given type ID exists
     * @param {string} typeId - The ID of the SelfDefFundAccountType to check
     * @returns {boolean} - True if exists, false otherwise
     */
    hasSelfDefFundAccount(typeId) {
        return this._selfDefFundDoubles.some(item =>
            item.selfDefFundAccountType && item.selfDefFundAccountType.id === typeId
        );
    }

    // 添加所有支持的Metal账户，没有添加，已有不重复添加
    addAllSupportMetalAccount() {
        let customerFundAccountTypeList = Engine.profile.org.customerFundAccountTypeList;

        for (let i = 0; i < customerFundAccountTypeList.length; i++) {
            let accountType = customerFundAccountTypeList[i];
           
                this.addSelfDefFundAccount(new SelfDefFundDouble(accountType, CsDouble.zero(),CsDouble.zero()));
           
        }       
    }


    /**
     * Clear all SelfDefFundDouble objects
     */
    clear() {
        this._selfDefFundDoubles = [];
    }

    removeCountIsZeroItemsAndClearExpectCount() {

        this._selfDefFundDoubles = this._selfDefFundDoubles.filter(item => !item.count.equal(CsDouble.zero()));

        this._selfDefFundDoubles.forEach(item => {
            item.expectCount = CsDouble.zero();
        });
    }

    // 判断来金，付金是否均为空
    checkTransactionIsEmpty() { 

        // 更改为 for 循环
        for (let i = 0; i < this._selfDefFundDoubles.length; i++) { 
            if(this._selfDefFundDoubles[i]._inCount != null || this._selfDefFundDoubles[i]._outCount != null){
                return false;
            }
        }

        return true;
    }

    /**
     * Clone this OrderSelfDefFundData object
     * @returns {OrderSelfDefFundData}
     */
    clone() {
        const cloned = new OrderSelfDefFundData();
        cloned._selfDefFundDoubles = this._selfDefFundDoubles.map(item => {
            // Assuming SelfDefFundDouble has a clone method or we create a new instance
            return new SelfDefFundDouble(
                item.selfDefFundAccountType ? SelfDefFundAccountType.clone(item.selfDefFundAccountType) : null,
                item.count
            );
        });
        return cloned;
    }

    /**
     * Create from JSON
     * @param {Array} json - Array of JSON objects representing SelfDefFundDouble
     * @returns {OrderSelfDefFundData}
     */
    static fromJson(jsonStr) {

        if (!jsonStr) {
            return null;
        }

        let json = JSON.parse(jsonStr);

        let orderSelfDefFundData = new OrderSelfDefFundData();
        if (Array.isArray(json)) {
            orderSelfDefFundData._selfDefFundDoubles = json.map(item => SelfDefFundDouble.fromJson(item));
        }
        return orderSelfDefFundData;
    }

    /**
     * Convert to JSON
     * @returns {Array} - Array of JSON representations
     */
    toJson() {
        // Implementation would depend on how SelfDefFundDouble is converted to JSON
        // This is a placeholder - you would need to implement the actual logic
        return this._selfDefFundDoubles.map(item => item.toJson ? item.toJson() : {});
    }

    toJsonStr() {
        return JSON.stringify(this.toJson());
    }
    
    
    // 交易记录
    toJsonForTransition() {
        // Implementation would depend on how SelfDefFundDouble is converted to JSON
        // This is a placeholder - you would need to implement the actual logic

        // 过滤 _selfDefFundDoubles 中记录的 inCount outCount 均为空的数据
        const accountRecords = this._selfDefFundDoubles.filter(item => item.inCount != null || item.outCount != null);

        return accountRecords.map(item => item.toJsonForTransition ? item.toJsonForTransition() : {});
    }
    toJsonStrForTransition() { 
         return JSON.stringify(this.toJsonForTransition());
    }    
}